package client

import (
	"fmt"
	"sync"
	"time"

	"github.com/louloulin/dataflare/pkg/controller/metadata"
)

// ClientStatus 表示客户端状态
type ClientStatus int

const (
	// ClientStatusConnected 表示已连接状态
	ClientStatusConnected ClientStatus = iota
	// ClientStatusDisconnected 表示已断开状态
	ClientStatusDisconnected
	// ClientStatusIdle 表示空闲状态
	ClientStatusIdle
	// ClientStatusBusy 表示忙碌状态
	ClientStatusBusy
)

// String 返回客户端状态的字符串表示
func (s ClientStatus) String() string {
	switch s {
	case ClientStatusConnected:
		return "connected"
	case ClientStatusDisconnected:
		return "disconnected"
	case ClientStatusIdle:
		return "idle"
	case ClientStatusBusy:
		return "busy"
	default:
		return "unknown"
	}
}

// ClientInfo 表示客户端信息
type ClientInfo struct {
	// ID 是客户端ID
	ID string
	// Address 是客户端地址
	Address string
	// Status 是客户端状态
	Status ClientStatus
	// ConnectedAt 是连接时间
	ConnectedAt time.Time
	// LastActivityAt 是最后活动时间
	LastActivityAt time.Time
	// Metadata 是客户端元数据
	Metadata map[string]string
}

// NewClientInfo 创建一个新的客户端信息
func NewClientInfo(id, address string) *ClientInfo {
	now := time.Now()
	return &ClientInfo{
		ID:             id,
		Address:        address,
		Status:         ClientStatusConnected,
		ConnectedAt:    now,
		LastActivityAt: now,
		Metadata:       make(map[string]string),
	}
}

// UpdateActivity 更新活动时间
func (ci *ClientInfo) UpdateActivity() {
	ci.LastActivityAt = time.Now()
}

// UpdateStatus 更新状态
func (ci *ClientInfo) UpdateStatus(status ClientStatus) {
	ci.Status = status
	ci.UpdateActivity()
}

// UpdateMetadata 更新元数据
func (ci *ClientInfo) UpdateMetadata(metadata map[string]string) {
	ci.Metadata = metadata
	ci.UpdateActivity()
}

// ClientCoordinator 表示客户端协调器
type ClientCoordinator struct {
	// clients 是客户端映射表
	clients map[string]*ClientInfo
	// metadataManager 是元数据管理器
	metadataManager *metadata.MetadataManager
	// mu 是互斥锁
	mu sync.RWMutex
}

// NewClientCoordinator 创建一个新的客户端协调器
func NewClientCoordinator(metadataManager *metadata.MetadataManager) *ClientCoordinator {
	return &ClientCoordinator{
		clients:         make(map[string]*ClientInfo),
		metadataManager: metadataManager,
	}
}

// RegisterClient 注册客户端
func (cc *ClientCoordinator) RegisterClient(id, address string) (*ClientInfo, error) {
	cc.mu.Lock()
	defer cc.mu.Unlock()

	// 检查是否已存在
	if _, exists := cc.clients[id]; exists {
		return nil, fmt.Errorf("client %s already registered", id)
	}

	// 创建客户端信息
	clientInfo := NewClientInfo(id, address)
	cc.clients[id] = clientInfo

	// 创建元数据
	if cc.metadataManager != nil {
		data := map[string]interface{}{
			"id":              id,
			"address":         address,
			"status":          ClientStatusConnected.String(),
			"connected_at":    clientInfo.ConnectedAt.Format(time.RFC3339),
			"last_activity_at": clientInfo.LastActivityAt.Format(time.RFC3339),
			"metadata":        clientInfo.Metadata,
		}
		_, err := cc.metadataManager.Create(metadata.MetadataTypeClient, id, data)
		if err != nil {
			delete(cc.clients, id)
			return nil, fmt.Errorf("failed to create client metadata: %w", err)
		}
	}

	return clientInfo, nil
}

// UnregisterClient 注销客户端
func (cc *ClientCoordinator) UnregisterClient(id string) error {
	cc.mu.Lock()
	defer cc.mu.Unlock()

	// 检查是否存在
	if _, exists := cc.clients[id]; !exists {
		return fmt.Errorf("client %s not found", id)
	}

	// 删除客户端信息
	delete(cc.clients, id)

	// 删除元数据
	if cc.metadataManager != nil {
		err := cc.metadataManager.Delete(metadata.MetadataTypeClient, id)
		if err != nil {
			return fmt.Errorf("failed to delete client metadata: %w", err)
		}
	}

	return nil
}

// GetClient 获取客户端
func (cc *ClientCoordinator) GetClient(id string) (*ClientInfo, bool) {
	cc.mu.RLock()
	defer cc.mu.RUnlock()

	client, ok := cc.clients[id]
	return client, ok
}

// GetAllClients 获取所有客户端
func (cc *ClientCoordinator) GetAllClients() []*ClientInfo {
	cc.mu.RLock()
	defer cc.mu.RUnlock()

	clients := make([]*ClientInfo, 0, len(cc.clients))
	for _, client := range cc.clients {
		clients = append(clients, client)
	}
	return clients
}

// UpdateClientStatus 更新客户端状态
func (cc *ClientCoordinator) UpdateClientStatus(id string, status ClientStatus) error {
	cc.mu.Lock()
	defer cc.mu.Unlock()

	// 检查是否存在
	client, exists := cc.clients[id]
	if !exists {
		return fmt.Errorf("client %s not found", id)
	}

	// 更新状态
	client.UpdateStatus(status)

	// 更新元数据
	if cc.metadataManager != nil {
		meta, exists := cc.metadataManager.Get(metadata.MetadataTypeClient, id)
		if exists {
			data := meta.Data
			data["status"] = status.String()
			data["last_activity_at"] = client.LastActivityAt.Format(time.RFC3339)
			_, err := cc.metadataManager.Update(metadata.MetadataTypeClient, id, data)
			if err != nil {
				return fmt.Errorf("failed to update client metadata: %w", err)
			}
		}
	}

	return nil
}

// UpdateClientMetadata 更新客户端元数据
func (cc *ClientCoordinator) UpdateClientMetadata(id string, clientMetadata map[string]string) error {
	cc.mu.Lock()
	defer cc.mu.Unlock()

	// 检查是否存在
	client, exists := cc.clients[id]
	if !exists {
		return fmt.Errorf("client %s not found", id)
	}

	// 更新元数据
	client.UpdateMetadata(clientMetadata)

	// 更新元数据
	if cc.metadataManager != nil {
		meta, exists := cc.metadataManager.Get(metadata.MetadataTypeClient, id)
		if exists {
			data := meta.Data
			data["metadata"] = clientMetadata
			data["last_activity_at"] = client.LastActivityAt.Format(time.RFC3339)
			_, err := cc.metadataManager.Update(metadata.MetadataTypeClient, id, data)
			if err != nil {
				return fmt.Errorf("failed to update client metadata: %w", err)
			}
		}
	}

	return nil
}

// GetClientsByStatus 获取指定状态的客户端
func (cc *ClientCoordinator) GetClientsByStatus(status ClientStatus) []*ClientInfo {
	cc.mu.RLock()
	defer cc.mu.RUnlock()

	clients := make([]*ClientInfo, 0)
	for _, client := range cc.clients {
		if client.Status == status {
			clients = append(clients, client)
		}
	}
	return clients
}

// GetConnectedClients 获取已连接的客户端
func (cc *ClientCoordinator) GetConnectedClients() []*ClientInfo {
	return cc.GetClientsByStatus(ClientStatusConnected)
}

// GetIdleClients 获取空闲的客户端
func (cc *ClientCoordinator) GetIdleClients() []*ClientInfo {
	return cc.GetClientsByStatus(ClientStatusIdle)
}

// GetBusyClients 获取忙碌的客户端
func (cc *ClientCoordinator) GetBusyClients() []*ClientInfo {
	return cc.GetClientsByStatus(ClientStatusBusy)
}

// ClientRequest 表示客户端请求
type ClientRequest struct {
	// ClientID 是客户端ID
	ClientID string
	// RequestID 是请求ID
	RequestID string
	// RequestType 是请求类型
	RequestType string
	// Data 是请求数据
	Data map[string]interface{}
	// Timestamp 是请求时间戳
	Timestamp time.Time
}

// ClientResponse 表示客户端响应
type ClientResponse struct {
	// ClientID 是客户端ID
	ClientID string
	// RequestID 是请求ID
	RequestID string
	// Success 表示是否成功
	Success bool
	// Error 是错误信息
	Error string
	// Data 是响应数据
	Data map[string]interface{}
	// Timestamp 是响应时间戳
	Timestamp time.Time
}

// ClientRequestHandler 表示客户端请求处理器
type ClientRequestHandler interface {
	// HandleRequest 处理请求
	HandleRequest(request *ClientRequest) *ClientResponse
}

// ClientRequestRouter 表示客户端请求路由器
type ClientRequestRouter struct {
	// handlers 是处理器映射表
	handlers map[string]ClientRequestHandler
	// mu 是互斥锁
	mu sync.RWMutex
}

// NewClientRequestRouter 创建一个新的客户端请求路由器
func NewClientRequestRouter() *ClientRequestRouter {
	return &ClientRequestRouter{
		handlers: make(map[string]ClientRequestHandler),
	}
}

// RegisterHandler 注册处理器
func (crr *ClientRequestRouter) RegisterHandler(requestType string, handler ClientRequestHandler) {
	crr.mu.Lock()
	defer crr.mu.Unlock()
	crr.handlers[requestType] = handler
}

// UnregisterHandler 注销处理器
func (crr *ClientRequestRouter) UnregisterHandler(requestType string) {
	crr.mu.Lock()
	defer crr.mu.Unlock()
	delete(crr.handlers, requestType)
}

// Route 路由请求
func (crr *ClientRequestRouter) Route(request *ClientRequest) *ClientResponse {
	crr.mu.RLock()
	handler, ok := crr.handlers[request.RequestType]
	crr.mu.RUnlock()

	if !ok {
		return &ClientResponse{
			ClientID:  request.ClientID,
			RequestID: request.RequestID,
			Success:   false,
			Error:     fmt.Sprintf("no handler for request type %s", request.RequestType),
			Timestamp: time.Now(),
		}
	}

	return handler.HandleRequest(request)
}
